/*
 * @Description:共享
 * @Author: maskMan
 * @LastEditTime: 2025-03-12 12:45:40
 */
import { util } from "../public/util";
import { NShop, NTarget, NUser, Report } from "../types/share";
import Mondb from "./mondb";
import { Table, TActionRecord, TAdmin, TShop, TShopRecord, TTask, TUser } from "./struct";
import { admin } from "../public/config";
import { jwtSign } from "../public/httpServe";
import { getWeightScore } from "../public/gameApp";
export default class Joint {
  /**创建管理员账号 */
  public static async createAdmin(): Promise<any> {
    try {
      const keylist = ["account", "password", "name", "ident"] as any;
      const roles: any = {
        客服管理: { 编辑权限: true, 创建权限: true, 删除权限: true },
        客服用户: { 查看权限: true, 删除权限: true, 编辑权限: { 普通会员: true, 至尊会员: true, 高级会员: true } },
        直属用户: {
          查看权限: true,
          删除权限: true,
          编辑权限: { 普通会员: true, 至尊会员: true, 高级会员: true },
          创建权限: { 普通会员: true, 至尊会员: true, 高级会员: true }
        },
        游戏分类: { 创建权限: true, 删除权限: true, 编辑权限: true, 查看权限: true },
        奖励设置: { 编辑权限: true, 查看权限: true },
        礼物商城: { 编辑权限: true, 删除权限: true, 查看权限: true, 创建权限: true },
        兑换记录: { 编辑权限: true, 查看权限: true, 删除权限: true },
        操作记录: { 删除权限: true, 查看权限: true }
      };
      const temp: TAdmin = {
        account: admin.account,
        password: admin.password,
        name: admin.name,
        ident: "admin",
        roles: roles,
        regTime: util.formaDate("年-月-日 时:分:秒"),
        lastTime: util.formaDate("年-月-日 时:分:秒"),
        status: true
      };
      const ret = await Mondb.findOneData(Table.admin, { ident: "admin" }, keylist);
      if (ret) {
        if (util.isEqual(ret, temp) == false) {
          console.log(`更新了超级管理员 ${admin.account}`);
          return await Mondb.updateOneData(Table.admin, { ident: "admin" }, temp);
        }
        console.log(`超级管理员 ${admin.account}`);
        return Promise.resolve(true);
      }
      console.log(`创建了超级管理员 ${admin.account}`);
      return await Mondb.creatOneData<Table.admin>(Table.admin, temp);
    } catch (error) {
      console.log("createAdmin", error);
    }
  }
  /**创建管理员账号 */
  public static async createWeight(): Promise<any> {
    const temp = {
      WID: 1,
      timeBase1: 5,
      timeBase2: 5,
      scoreBase3: 100,
      scoreRatio: 1000,
      coinsRatio: 5,
      pointRatio: 5
    };
    const ret = await Mondb.findOneData(Table.weight, { WID: 1 });
    if (!ret) {
      console.log(`创建了权重列表`);
      return await Mondb.creatOneData<Table.weight>(Table.weight, temp);
    }
  }
  //创建用户
  public static async createUser(reg): Promise<boolean | -1> {
    try {
      const result = await Mondb.findOneData(Table.user, { account: reg.account });
      if (result) {
        return Promise.resolve(null);
      }
      const temp: TUser = {
        account: reg.account,
        password: reg.password,
        parent: reg.parent || "admin",
        name: reg.name,
        age: reg.age,
        vipLevel: reg.vipLevel || "初级会员",
        coins: reg.coins || 0,
        points: reg.points || 0,
        regTime: util.formaDate("年-月-日 时:分:秒"),
        loginCount: 0,
        referrer: reg.referrer || null,
        address: null,
        ipone: null,
        endTime: reg.endTime || null,
        lastTime: null,
        commit: reg.commit || "",
        status: reg.status == undefined || reg.status == null || reg.status == false ? false : true
      };
      if (reg.referrer) {
        const isExist = await Mondb.findOneData<Table.user>(Table.user, { account: reg.referrer });
        if (!isExist) {
          console.error("createUser推荐用户不存在", reg);
          return Promise.resolve(-1);
        }
      }
      const retValue = await Mondb.creatOneData<Table.user>(Table.user, temp);
      return Promise.resolve(retValue ? (temp as any) : null);
    } catch (error) {
      console.error("createUser参数不正确1", reg, error);
      return Promise.resolve(null);
    }
  }
  //用户登录
  public static async loginUser(login: NUser.Login): Promise<{ data: NUser.Info; sign: string } | -1 | -2 | -3> {
    try {
      const result = await Mondb.findOneAndUpdate<Table.user>(
        Table.user,
        { account: login.account, password: login.password },
        { $inc: { loginCount: 1 }, $set: { lastTime: util.formaDate("年-月-日 时:分:秒") } }
      );
      if (!result) {
        console.log("loginUser失败", login);
        return Promise.resolve(null);
      }
      if (!result.endTime) {
        console.log("loginUser失败", login);
        return Promise.resolve(-1);
      }
      const timeStamp = new Date(result.endTime).getTime();
      if (timeStamp < util.now()) {
        return Promise.resolve(-2);
      }
      if (!result.status) {
        return Promise.resolve(-3);
      }
      const retData: NUser.Info = {
        account: result.account,
        name: result.name,
        age: result.age,
        referrer: result.referrer || "",
        vipLevel: result.vipLevel,
        coins: result.coins || 0,
        points: result.points || 0,
        endTime: result.endTime || "",
        lastTime: result.lastTime || ""
      };
      const sign = jwtSign({
        id: result._id.toString(),
        uid: result.UID,
        account: result.account,
        loginCount: result.loginCount
      });
      return Promise.resolve({ data: retData, sign: sign });
    } catch (error) {
      console.error("loginUser参数不正确1", login, error);
      return Promise.resolve(null);
    }
  }
  //修改用户信息
  public static async modifyUser(modify: NUser.Modify): Promise<boolean> {
    try {
      const temp: any = {};
      if (modify.newPassword) {
        temp.password = modify.newPassword;
      }
      if (modify.age) {
        temp.age = modify.age;
      }
      const result = await Mondb.findOneAndUpdate<Table.user>(Table.user, { account: modify.account, password: modify.password }, temp, {
        select: "account"
      });
      if (!result) {
        console.log("modifyUser修改失败", modify);
        return Promise.resolve(null);
      }
      return Promise.resolve(true);
    } catch (error) {
      console.error("modifyUser 报错", modify, error);
      return Promise.resolve(null);
    }
  }
  //认证密码
  public static async userAuth(auth: NUser.Modify): Promise<any> {
    try {
      const keylist = ["account", "loginCount"];
      const result = await Mondb.findOneData<Table.user>(Table.user, { account: auth.account, password: auth.password }, keylist);
      if (!result) {
        console.log("userAuth修改失败", auth);
        return Promise.resolve(null);
      }
      return Promise.resolve(result);
    } catch (error) {
      console.error("userAuth报错", auth, error);
      return Promise.resolve(null);
    }
  }
  //获取训练营列表
  public static async getUserInfo(account: string, ...keyList): Promise<Partial<TUser>> {
    try {
      const result = await Mondb.findOneData<Table.user>(Table.user, { account: account }, keyList);
      if (!result) {
        console.log("getUserInfo获取失败", account);
        return Promise.resolve(null);
      }
      return Promise.resolve(result);
    } catch (error) {
      console.error("getUserInfo报错", account, error);
      return Promise.resolve(null);
    }
  }
  //获取小目标数据
  public static async getTargetData(account: string, ...keyList): Promise<Partial<TTask>> {
    try {
      const result = await Mondb.findOneData<Table.task>(Table.task, { account: account }, keyList);
      if (!result) {
        console.log("getTargetData获取失败", account);
        return Promise.resolve(null);
      }
      return Promise.resolve(result);
    } catch (error) {
      console.error("getTargetData报错", account, error);
      return Promise.resolve(null);
    }
  }
  //修改用户信息
  public static async createTarget(
    account: string,
    createData: NTarget.Create,
    itemData: NTarget.ItemData,
    taskList: NTarget.Task[]
  ): Promise<Partial<TTask>> {
    try {
      const retValue = await Mondb.creatOneData<Table.task>(Table.task, { account, createData, itemData, taskList });
      return Promise.resolve(retValue || null);
    } catch (error) {
      console.error("createTarget 报错", account, createData, itemData, taskList, error);
      return Promise.resolve(null);
    }
  }
  //删除小目标数据
  public static async delTargetData(account: string): Promise<boolean> {
    try {
      const findRet = await Mondb.findOneAndUpdate(Table.user, { account, points: { $gte: 3 } }, { $inc: { points: -3 } });
      if (findRet) {
        const result = await Mondb.deleteOneData(Table.task, { account: account });
        if (!result) {
          console.log("delTargetData删除失败", account);
          await Mondb.findOneAndUpdate(Table.user, { account }, { $inc: { points: 3 } });
          return Promise.resolve(null);
        }
        console.log("delTargetData删除成功", account);
        return Promise.resolve(true);
      }
      console.log("删除失败", account);
      return Promise.resolve(null);
    } catch (error) {
      console.error("delTargetData报错", account, error);
      return Promise.resolve(null);
    }
  }
  //更新小目标数据
  public static async updateTargetData(
    account: string,
    currTask: NTarget.Task,
    itemData: NTarget.ItemData,
    recordData: NTarget.Record[]
  ): Promise<boolean> {
    try {
      if (currTask.markStatus == -1) {
        const reword = [5 * 60 * 1000, 30 * 60 * 1000, 60 * 60 * 1000];
        const costTime = itemData.totalTime - currTask.restTime;
        currTask.star = costTime >= reword[2] ? 3 : costTime >= reword[1] ? 2 : costTime >= reword[0] ? 1 : 0;
      }
      let total = 0;
      recordData.forEach(v => {
        let score = v.actionKind == "animate" ? 0 : v.score;
        let errCount = v.actionKind == "animate" ? 0 : v.errCount;
        let costTime = v.endTime - v.startTime;
        let fixTime = itemData.limitTime;
        let coins = getWeightScore(score, errCount, fixTime, costTime);
        total += coins;
      });
      currTask.reword += total;
      if (currTask.markStatus == -1 && currTask.reword == 0 && currTask.star == 0) {
        currTask.completed = true;
      }
      const result = await Mondb.updateOneData(Table.task, { account, "taskList.dayIndex": currTask.dayIndex }, { "taskList.$": currTask });
      if (result) {
        console.log("updateTargetData更新成功", account);
        return Promise.resolve(true);
      }
      console.log("updateTargetData更新失败", account);
      return Promise.resolve(null);
    } catch (error) {
      console.error("updateTargetData报错", account, error);
      return Promise.resolve(null);
    }
  }
  //创建小目标数据
  public static async createTargetData(account: string, taskList: Partial<TTask>): Promise<Partial<TTask>> {
    try {
      const result = await Mondb.findOneAndUpdate(Table.task, { account }, taskList, { select: "taskList itemData" });
      if (result) {
        console.log("createTargetData更新成功", account);
        return Promise.resolve(result);
      }
      console.log("createTargetData更新失败", account);
      return Promise.resolve(null);
    } catch (error) {
      console.error("createTargetData报错", account, error);
      return Promise.resolve(null);
    }
  }
  //更新小目标记录报告
  public static async updateTargetReport(
    account: string,
    recordData: NTarget.Record[],
    itemData: NTarget.ItemData,
    currTask: NTarget.Task
  ): Promise<boolean> {
    try {
      const currDay = util.currDay();
      let createReport = await Mondb.findOneData<Table.targetRecord>(Table.targetRecord, { account, date: currDay });
      const groupList = itemData.groupList;
      let recordMaps: Report.TargetRecordMaps;
      const taskLen = currTask.taskList.filter(v => v?.animateData?.completed || v?.trainData?.completed).length;
      if (createReport) {
        createReport.costTime = util.timeRestChange((itemData.totalTime - currTask.restTime) * 1000);
        createReport.fillRate = `${taskLen}/${itemData.itemCount}`;
        createReport.score = currTask.reword;
        recordMaps = createReport.recordMaps;
      } else {
        recordMaps = {};
        createReport = {
          recordMaps: recordMaps,
          planCount: currTask.dayIndex,
          costTime: util.timeRestChange((itemData.totalTime - currTask.restTime) * 1000),
          planTime: util.timeRestChange(itemData.totalTime * 1000),
          itemCount: itemData.itemCount,
          score: currTask.reword,
          fillRate: `${taskLen}/${itemData.itemCount}`,
          date: currDay
        };
      }
      for (let i = 0; i < groupList.length; i++) {
        const typeName = groupList[i];
        if (!recordMaps[typeName]) {
          recordMaps[typeName] = [];
        }
        for (let k = 0; k < recordData.length; k++) {
          const itemRecord = recordData[k];
          const costTime = itemRecord.endTime - itemRecord.startTime;
          const planTime = util.timeRestChange(itemRecord.fixTime == undefined ? itemData.limitTime * 60 : itemRecord.fixTime);
          const reportData: Report.TargetRecord = {
            typeName: itemRecord.typeName as any,
            gameName: itemRecord.gameName,
            costTime: util.timeRestChange(costTime),
            planTime: planTime,
            score: itemRecord.score,
            errCount: itemRecord.errCount
          };
          const index = recordMaps[typeName].findIndex(v => v.id == itemRecord.id);
          if (index >= 0) {
            recordMaps[index] = reportData;
          } else {
            recordMaps[typeName].push(reportData);
          }
        }
      }
      const result = await Mondb.updateOneData(Table.targetRecord, { account, date: currDay }, createReport, { upsert: true });
      if (result) {
        return Promise.resolve(true);
      }
      console.log("updateReport更新失败", account, recordData, itemData, currTask);
      return Promise.resolve(null);
    } catch (error) {
      console.error("updateReport报错", account, error);
      return Promise.resolve(null);
    }
  }
  //获取小目标报告
  public static async getTargetDiary(account: string, date: string): Promise<Partial<TTask>> {
    try {
      const temp = date ? { account, date } : { account };
      const result = await Mondb.findManyData<Table.targetRecord>(Table.targetRecord, temp);
      if (result) {
        console.log("getTargetDiary获取成功", account);
        if (result && date) {
          return Promise.resolve(result[0] as any);
        } else {
          return Promise.resolve(result as any);
        }
      }
      return Promise.resolve(null);
    } catch (error) {
      console.error("getTargetDiary报错", account, error);
      return Promise.resolve(null);
    }
  }
  //更新奖励信息
  public static async updateTargetReword(account: string, currTask: NTarget.Task): Promise<boolean> {
    try {
      const coins = currTask.reword;
      const points = currTask.star;
      currTask.completed = true;
      const result = await Mondb.updateOneData(Table.task, { account, "taskList.dayIndex": currTask.dayIndex }, { "taskList.$": currTask });
      if (result) {
        if (coins == 0 && points == 0) {
          console.error("updateReword奖励领取成功", account, currTask);
          return Promise.resolve(true);
        }
        const findRet = await Mondb.findOneAndUpdate(Table.user, { account }, { $inc: { points: points, coins: coins } });
        if (findRet) {
          console.error("updateReword奖励领取成功", account, currTask);
          return Promise.resolve(true);
        }
      }
      console.log("updateReword奖励领取失败", account, currTask);
      return Promise.resolve(null);
    } catch (error) {
      console.error("updateReport报错", account, error);
      return Promise.resolve(null);
    }
  }
  //更新奖励金币
  public static async upUserCoins(account: string, coins: number): Promise<any> {
    try {
      const findRet = await Mondb.findOneAndUpdate(Table.user, { account }, { $inc: { coins: coins } });
      if (findRet) {
        console.error("upUserCoins金币领取成功", account, coins);
        return Promise.resolve(findRet);
      }
      console.log("upUserCoins奖励领取失败", account, coins);
      return Promise.resolve(null);
    } catch (error) {
      console.error("updateReport报错", account, error);
      return Promise.resolve(null);
    }
  }
  //获取商店列表
  public static async getShops(type: NShop.typeName): Promise<TShop[]> {
    try {
      const result: any = await Mondb.findManyData<Table.shop>(Table.shop, { groupType: type });
      if (!result) {
        console.log("getShops获取失败", type);
        return Promise.resolve(null);
      }
      return Promise.resolve(result);
    } catch (error) {
      console.error("getShops报错", type, error);
      return Promise.resolve(null);
    }
  }
  //创建商品
  public static async createShops(type: NShop.typeName, data: NShop.Info): Promise<boolean> {
    try {
      const result = await Mondb.updateOneData(Table.shop, {}, { $push: { [type]: data } }, { upsert: true });
      if (!result) {
        console.log("createShops创建失败", type, data);
        return Promise.resolve(null);
      }
      return Promise.resolve(true);
    } catch (error) {
      console.error("createShops报错", type, data, error);
      return Promise.resolve(null);
    }
  }
  //删除商品
  public static async delShops(type: NShop.typeName, sid: string): Promise<boolean> {
    try {
      const result = await Mondb.updateOneData(Table.shop, {}, { $pull: { [type]: { sid } } });
      if (!result) {
        console.log("delShops删除失败", type, sid);
        return Promise.resolve(null);
      }
      return Promise.resolve(true);
    } catch (error) {
      console.error("delShops报错", type, sid, error);
      return Promise.resolve(null);
    }
  }
  //购买商品
  public static async buyShop(account, type: NShop.typeName, buyInfo: NShop.Buy): Promise<boolean> {
    try {
      const sid = buyInfo.sid;
      const shopData: any = await Mondb.findOneData<Table.shop>(Table.shop, {
        SID: sid,
        stock: { $gte: 0 }
      });
      if (!shopData) {
        console.log("buyShop未找到商品", type, sid);
        return Promise.resolve(null);
      }
      const shops = shopData;
      const findRet = await Mondb.updateOneData(
        Table.user,
        { account, points: { $gte: shops.points }, coins: { $gte: shops.price } },
        { $inc: { points: shops.points * -1, coins: shops.price * -1 } },
        { select: "" }
      );
      if (!findRet) {
        console.log("buyShop金币数不足", type, sid);
        return Promise.resolve(null);
      }
      const temp: TShopRecord = {
        timeStamp: util.now(),
        name: buyInfo.contact.name,
        ipone: buyInfo.contact.ipone,
        address: buyInfo.contact.address,
        status: "未发货",
        account: account,
        shopId: sid,
        shopName: shops.name
      };
      const result = await Mondb.creatOneData(Table.shopRecord, temp);
      if (!result) {
        console.log("buyShop购买失败", type, sid, buyInfo);
        return Promise.resolve(null);
      }
      //库存自减1
      await Mondb.updateOneData(Table.shop, { SID: sid }, { $inc: { stock: -1 } });
      console.log("buyShop购买成功", type, sid, buyInfo);
      return Promise.resolve(true);
    } catch (error) {
      console.error("buyShop报错", type, error);
      return Promise.resolve(null);
    }
  }
  //创建动作记录
  public static async createActionRecord(data: TActionRecord): Promise<boolean> {
    try {
      let content = data?.commit;
      if (data?.commit && typeof data?.commit == "object") {
        content = JSON.stringify(data?.commit);
      }
      const record = {
        account: data.account,
        timeStamp: util.now(),
        actionType: data.actionType,
        creator: data.creator,
        commit: content
      };
      const result = await Mondb.creatOneData(Table.actionRecord, record);
      if (!result) {
        console.log("createActionRecord创建失败", data);
        return Promise.resolve(null);
      }
      return Promise.resolve(true);
    } catch (error) {
      console.error("createActionRecord报错", data, error);
      return Promise.resolve(null);
    }
  }
}
